<template>
  <div class="flex h-full flex-col">
    <div class="flex justify-between">
      <el-form inline label-width="80px">
        <el-form-item label="资源名称">
          <el-input v-model="searchQuery" placeholder="搜索资源名称/编码" clearable class="w-48" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch" :icon="Search">搜索</el-button>
          <el-button @click="handleReset" :icon="Refresh">重置</el-button>
        </el-form-item>
      </el-form>
      <el-button type="primary" @click="handleAddRoot" :icon="Plus"> 添加根资源 </el-button>
    </div>
    <div class="h-0 grow overflow-y-auto">
      <el-tree
        ref="resourceTree"
        v-loading="loading"
        :data="resourceTreeData"
        :props="treeProps"
        :default-expand-all="true"
        node-key="id"
      >
        <template #default="{ node, data }">
          <div class="group flex w-full items-center justify-between">
            <span>{{ node.label }}</span>
            <span v-if="data.code" class="ml-2 flex items-center gap-1 text-xs text-gray-500"
              >({{ data.code }})
            </span>
            <div class="flex items-center gap-4">
              <el-tag v-if="data.type === 2" type="success" size="small">按钮</el-tag>
              <el-tag v-if="data.type === 1" type="primary" size="small">菜单</el-tag>
              <div class="invisible group-hover:visible">
                <el-button
                  type="text"
                  size="small"
                  @click.stop="handleAddChild(data)"
                  title="添加子资源"
                >
                  <el-icon><Plus /></el-icon>
                </el-button>
                <el-button type="text" size="small" @click.stop="handleEdit(data)" title="编辑资源">
                  <el-icon><Edit /></el-icon>
                </el-button>
                <el-button
                  type="text"
                  size="small"
                  @click.stop="handleDelete(data)"
                  title="删除资源"
                  danger
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </div>
          </div>
        </template>
      </el-tree>
    </div>
    <!-- 批量操作按钮 -->
    <div class="mt-4 text-right">
      <el-button
        type="danger"
        @click="handleBatchDelete"
        :disabled="!hasSelected"
        :loading="batchLoading"
      >
        <el-icon><Delete /></el-icon>
        批量删除
      </el-button>
    </div>

    <!-- 资源表单对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle">
      <el-form ref="resourceForm" :model="formData" :rules="formRules" label-width="100px">
        <el-form-item label="资源名称" prop="name">
          <el-input v-model="formData.name" placeholder="请输入资源名称" />
        </el-form-item>
        <el-form-item label="资源编码" prop="code">
          <el-input v-model="formData.code" placeholder="请输入资源编码" />
        </el-form-item>
        <el-form-item label="资源类型" prop="type">
          <el-select v-model="formData.type" placeholder="请选择资源类型">
            <el-option label="菜单" :value="1" />
            <el-option label="按钮" :value="2" />
          </el-select>
        </el-form-item>
        <el-form-item label="路由路径" prop="path">
          <el-input v-model="formData.path" placeholder="请输入路由路径" />
        </el-form-item>
        <el-form-item label="组件路径" prop="component">
          <el-input v-model="formData.component" placeholder="请输入组件路径" />
        </el-form-item>
        <el-form-item label="图标" prop="icon" v-if="formData.type === 1">
          <el-popover ref="iconPopover" placement="bottom" :width="553" trigger="click">
            <template #reference>
              <el-input v-model="formData.icon" placeholder="请选择图标" readonly>
                <template #prefix v-if="formData.icon">
                  <div :class="'iconfont icon-' + formData.icon" />
                </template>
              </el-input>
            </template>
            <div>
              <el-scrollbar height="400px">
                <div class="flex flex-wrap justify-center gap-1 p-2">
                  <div
                    class="flex w-16 cursor-pointer flex-col items-center justify-center rounded p-2 transition hover:bg-(--el-fill-color-light)"
                    @click="handleIconSelect(item.font_class)"
                    :title="item.font_class"
                    v-for="(item, index) in iconFontJson.glyphs"
                    :key="index"
                  >
                    <div :class="'iconfont icon-' + item.font_class" />
                    <div class="w-full truncate text-center text-xs">
                      {{ item.font_class }}
                    </div>
                  </div>
                </div>
              </el-scrollbar>
            </div>
          </el-popover>
        </el-form-item>
        <el-form-item label="排序号" prop="sort">
          <el-input-number controls-position="right" v-model="formData.sort" :min="0" />
        </el-form-item>
        <el-form-item label="是否隐藏" prop="isHidden">
          <el-switch v-model="formData.isHidden" />
        </el-form-item>
        <el-form-item label="是否缓存" prop="isCache" v-if="formData.type === 1">
          <el-switch v-model="formData.isCache" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-switch v-model="formData.status" :active-value="1" :inactive-value="0" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input
            v-model="formData.remark"
            type="textarea"
            placeholder="请输入备注信息"
            :rows="3"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="flex justify-end">
          <el-button @click="handleCancel">取消</el-button>
          <el-button type="primary" @click="handleSubmit" :loading="submitLoading">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import * as ResourceApi from '@/api/system/resource.api'
import iconFontJson from '@/assets/iconfont/iconfont.json'
import { to } from '@/utils/promise'
import { Delete, Edit, Plus, Refresh, Search } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { computed, onMounted, reactive, ref } from 'vue'

// 状态管理
const loading = ref(false)
const batchLoading = ref(false)
const submitLoading = ref(false)
const dialogVisible = ref(false)
const dialogTitle = ref('')
const searchQuery = ref('')
const resourceTree = ref()
const iconPopover = ref()
const selectedKeys = ref<number[]>([])
const hasSelected = computed(() => selectedKeys.value.length > 0)

// 表单数据
const formData = reactive<ResourceFormData>({
  id: undefined,
  parentId: 0,
  name: '',
  code: '',
  type: 1, // 默认菜单类型
  path: '',
  component: '',
  icon: '',
  sort: 0,
  isHidden: false,
  isCache: false,
  status: 1,
  remark: '',
  children: []
})

// 表单验证规则
const formRules = {
  name: [{ required: true, message: '请输入资源名称', trigger: 'blur' }],
  code: [{ required: true, message: '请输入资源编码', trigger: 'blur' }],
  type: [{ required: true, message: '请选择资源类型', trigger: 'change' }]
}

// 树形结构配置
const treeProps = {
  label: 'name',
  children: 'children',
  isLeaf: (data: any) => data.type === 2
}

// 资源树数据
const resourceTreeData = ref<ResourceFormData[]>([])

// 获取资源树
const getResourceTree = async () => {
  loading.value = true
  const [error, response] = await to(
    ResourceApi.getResourceTree({
      name: searchQuery.value,
      code: ''
      // type和status参数不传递或设为undefined，避免与后端*int8类型不匹配
    })
  )
  if (error) {
    ElMessage.error('获取资源树失败')
    return
  }
  resourceTreeData.value = response || []
  loading.value = false
}

// 选择图标
const handleIconSelect = (iconClass: string) => {
  formData.icon = iconClass
  iconPopover.value?.hide()
}

// 打开添加根资源对话框
const handleAddRoot = () => {
  resetForm()
  formData.parentId = 0 // 根资源的parentId通常为0
  dialogTitle.value = '添加根资源'
  dialogVisible.value = true
}

// 打开添加子资源对话框
const handleAddChild = (parentData: any) => {
  resetForm()
  formData.parentId = parentData.id
  dialogTitle.value = '添加子资源'
  dialogVisible.value = true
}

// 打开编辑资源对话框
const handleEdit = async (data: any) => {
  const [error, response] = await to(ResourceApi.getResourceById(data.id))
  if (error) {
    ElMessage.error('获取资源详情失败')
    return
  }
  const resource = response
  Object.assign(formData, {
    id: resource.id,
    parentId: resource.parentId,
    name: resource.name,
    code: resource.code,
    type: resource.type,
    path: resource.path,
    component: resource.component,
    icon: resource.icon,
    sort: resource.sort,
    isHidden: resource.isHidden,
    isCache: resource.isCache || false,
    status: resource.status,
    remark: resource.remark
  })
  dialogTitle.value = '编辑资源'
  dialogVisible.value = true
}

// 删除资源
const handleDelete = (data: any) => {
  ElMessageBox.confirm(`确定要删除资源"${data.name}"吗？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    const [error] = await to(ResourceApi.deleteResource(data.id))
    if (error) {
      ElMessage.error('删除失败')
      return
    }
    ElMessage.success('删除成功')
    getResourceTree()
  })
}

// 批量删除资源
const handleBatchDelete = () => {
  ElMessageBox.confirm(`确定要删除选中的${selectedKeys.value.length}个资源吗？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    batchLoading.value = true
    const [error] = await to(ResourceApi.batchDeleteResources(selectedKeys.value))
    if (error) {
      ElMessage.error('批量删除失败')
      return
    }
    ElMessage.success('批量删除成功')
    selectedKeys.value = []
    getResourceTree()
  })
}

// 重置表单
const resetForm = () => {
  Object.assign(formData, {
    id: undefined,
    parentId: 0,
    name: '',
    code: '',
    type: 1,
    path: '',
    component: '',
    icon: '',
    sort: 0,
    isHidden: false,
    isCache: false,
    status: 1,
    remark: ''
  })
}

// 取消操作
const handleCancel = () => {
  dialogVisible.value = false
  resetForm()
}

const resourceForm = ref()
// 提交表单
const handleSubmit = async () => {
  const formRef = resourceForm.value
  const [error] = await to<boolean, string>(formRef!.validate())
  if (error) {
    ElMessage.error(error || '表单验证失败')
    return
  }
  await formRef.validate()
  submitLoading.value = true

  if (formData.id) {
    // 编辑资源
    const [error] = await to(ResourceApi.updateResource(formData.id, formData))
    if (error) {
      ElMessage.error('更新失败')
      return
    }
  } else {
    // 新增资源
    const [error] = await to(ResourceApi.createResource(formData))
    if (error) {
      ElMessage.error('创建失败')
      return
    }
  }

  dialogVisible.value = false
  getResourceTree()
  submitLoading.value = false
}

// 搜索资源
const handleSearch = () => {
  getResourceTree()
}

// 监听搜索输入
searchQuery.value = ''

// 组件挂载时获取资源树
onMounted(() => {
  getResourceTree()
})

// 重置搜索
const handleReset = () => {
  searchQuery.value = ''
  getResourceTree()
}
</script>

<style scoped></style>
